package ay.shadow.security.handler;

import ay.shadow.core.utils.JwtTokenProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;

@Component
public class JwtAuthenticationFilter implements WebFilter {

    private final CustomReactiveAuthManager authManager;

    public JwtAuthenticationFilter(CustomReactiveAuthManager authManager) {
        this.authManager = authManager;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        // 1. 从请求头中获取Authorization令牌
        String token = extractToken(exchange);

        // 2. 验证令牌是否有效
        if (token != null ) {
            String username = JwtTokenProvider.getUsernameFromToken(token);
            if (JwtTokenProvider.validateToken(token,username)) {
                // 3. 从令牌中获取用户名


                // 4. 加载用户信息并设置认证上下文
//                    userDetailsService.findByUsername(username)
//                    .flatMap(userDetails -> {
                // 创建认证对象
                UsernamePasswordAuthenticationToken unauthentication =
                        new UsernamePasswordAuthenticationToken(
                                null,
                                token
                        );

//                SecurityContextHolder.getContext().setAuthentication(authentication);

                // 将认证信息存入安全上下文
                return authManager.authenticate(unauthentication)
                        // 5. 认证成功：设置SecurityContext
                        .flatMap(authenticated -> {
                            SecurityContext context = new SecurityContextImpl(authenticated);
                            // 将认证信息存入上下文
                            return chain.filter(exchange)
                                    .contextWrite(ReactiveSecurityContextHolder.withSecurityContext(Mono.just(context)));
                        })
                        // 6. 认证失败：继续过滤（后续授权阶段会返回401）
                        .onErrorResume(e -> chain.filter(exchange));
//                    });
            }
        }
        // 令牌无效或不存在，继续过滤链（后续Security配置会处理未认证请求）
        return chain.filter(exchange);
    }

    /**
     * 从请求头中提取JWT令牌
     */
    private String extractToken(ServerWebExchange exchange) {
        String authHeader = exchange.getRequest().getHeaders().getFirst("Authorization");

        // 检查Authorization头是否符合Bearer Token格式
        if (authHeader != null && authHeader.startsWith("Bearer ")) {
            return authHeader.substring(7); // 截取"Bearer "后面的令牌部分
        }

        return null;
    }
}

